(function($) {
	var Countdown = function($el) {
		var me = this;
		this.Settings;
		var timeout;
		var start;
		var from;

		$el.data('__countdown', this);

		var countdown = function() {
			timeout = setTimeout(function() {
				if ( !$el || !$el[0] ) return;
				var now = new Date();
				time_left = from - ((now.getTime() - start.getTime())/1000);
				if ( time_left <= me.Settings.to ) time_left = me.Settings.to;
				$el.html(time_left.toFixed(2));
				if ( time_left != me.Settings.to ) countdown();
			}, me.Settings.refresh);
		};

		var stop = function() {
			clearTimeout(timeout);
		};

		this.Init = function(settings) {
			stop();
			me.Settings = settings;
			start = new Date();
			from = settings.from || parseInt($el.html());
			if ( !from ) return;
			countdown();
		};

		this.Message = function(message, params) {
			switch(message) {
			case 'Stop' :
				return stop(params);
			break;
			}
		};
	};

	$.fn.countdown = function(params, message_params) {
		var settings = $.extend({
			from: null,
			to: 0,
			refresh: 100
		}, params);

		return this.each(function() {
			var $this = $(this);
			var __countdown;

			if ( (__countdown = $this.data('__countdown')) ) {
				if ( typeof params == 'string' ) {
					__countdown.Message(params, message_params);
				} else {
					__countdown.Init($.extend(__countdown.Settings, settings));
				}
				return;
			} else if ( typeof params == 'string' ) {
				return;
			}

			__countdown = new Countdown($this);
			__countdown.Init(settings);
		});
	};
})(jQuery);